//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_CONFIGURED_RENDER_TECHNIQUE_H
#define _UX_CONFIGURED_RENDER_TECHNIQUE_H

#include "IRenderTechnique.h"
#include "CRTPassManager.h"
#include "Passes/TRTMessage.h"
#include "Passes/IRTPass.h"
#include "ConfiguredRTTypes.h"

namespace Engine
{
namespace RenderUtils
{

	//
	// Configured Render Technique
	//

	class _EXPORT_ CConfiguredRenderTech : public IRenderTechnique
	{
	protected:
		struct _TProgramLayers
		{
			usize				uFirst,
								uLast;
			e_program::type		eType;
			///
			_TProgramLayers(): uFirst(0), uLast(0), eType(e_program::UNKNOWN) {}
			_TProgramLayers(usize first, e_program::type type): uFirst(first), uLast(first), eType(type) {}
		};

		typedef pod_array< IRTPass *>					rt_pass_array_t;
		typedef array< TMaterialStateLock >				layer_lock_array_t;
		typedef TCameraRenderQueue::camera_rq_array_t	camera_rq_array_t;
		typedef array< CBaseProgramShellPtr >			program_array_t;
		typedef array< _TProgramLayers >				prog_layers_array_t;

		
		class CBaseRTPass : public IRTPass
		{
		public:
			IPostProcessPtr		_pPostProcess;
			camera_rq_array_t	_aViewCameras,
								_aMiniviewCameras,
								_aLightCameras,
								_aReflectionCameras;
			FBO_t				_cFBO;
			CQueryObject		_cSamplesQuery;
			uint				_uInputIndex;
			bool				_bHasPostProcess;

		public:
			CBaseRTPass();
			~CBaseRTPass();

			void SetPostProcess(IPostProcessPtr &pPP);
			void Update(IRenderQueue *, uint);
			void Delete();

			virtual bool ProcessMessage(TRTMessage &);

			virtual EPassType GetPassType() const		{ return BASE; }
		};

	protected:
		rt_pass_array_t			_aPasses;
		program_array_t			_aPrograms;
		prog_layers_array_t		_aProgLayers;
		layer_lock_array_t		_aLayerLocks;
		CBaseRTPass				_cBase;
		e_technique::type		_eTechType;
		
	protected:
		virtual void _Destroy();
		virtual bool _Create(const TConfiguredRTInit &sInit);
		
		bool _LoadPrograms(const string_array_t &aPrograms);
		bool _FindProgram(e_program::type eType, e_program::type eMask, usize &uIndex);

	public:
		CConfiguredRenderTech();
		virtual ~CConfiguredRenderTech();

		bool Load(const char *pFileName);

		static void s_InitMetaData();


		// IRenderTechnique //
		virtual void Resize(const uvec2 &vDim);
		
		virtual void SetupRenderQueue(IRenderQueue *);

		virtual bool SetPostProcess(const IPostProcessBasePtr &pPP);
		virtual bool AddPostProcess(const IPostProcessBasePtr &pPP, uint uIndex);

		virtual bool GetProgram(e_program::type, e_render_layer::type, CBaseProgramShellPtr &);
		virtual void GetMaterialStateLock(e_render_layer::type, e_render_state_lock::type &);
		
		virtual void Render(IRenderQueue *, uint);
		virtual bool IsReady();

		//virtual e_render_layer::type	GetCurrentRenderLayer()		{ return _eCurrentLayer; }
		virtual e_technique::type		GetType() const				{ return _eTechType; }


		// CEngBaseObject //
		virtual void  Release();
	};


//-------------------------------------------------------------------

}	// RenderUtils
}	// Engine

#endif	// _UX_CONFIGURED_RENDER_TECHNIQUE_H